import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.Key;

public class Server5_5 {
    public static void main(String[] args) {
        String mode = "AES";
        ServerSocket serverForClient = null;
        Socket socketOnServer = null;
        DataOutputStream out = null;
        DataInputStream in = null;
        try{
            serverForClient = new ServerSocket(2010);
        }catch (IOException e1){
            System.out.println(e1);
        }
        String result;
        try{
            System.out.println("等待客户呼叫：");
            socketOnServer = serverForClient.accept();
            out = new DataOutputStream(socketOnServer.getOutputStream());
            in = new DataInputStream(socketOnServer.getInputStream());
            String cformula = in.readUTF();//读取密文
            byte cipher[] = H_B.parseHexStr2Byte(cformula);

            FileInputStream fp = new FileInputStream("Clientpub.txt");
            ObjectInputStream bp = new ObjectInputStream(fp);
            Key kp = (Key) bp.readObject();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(kp);

            byte[] kb = baos.toByteArray();
            out.writeUTF(kb.length + "");
            for (int i = 0; i < kb.length; i++) {
                out.writeUTF(kb[i] + "");
            }

            Thread.sleep(1000);
            int len = Integer.parseInt(in.readUTF());
            byte np[] = new byte[len];
            for (int i = 0;i<len;i++) {
                String temp = in.readUTF();
                np[i] = Byte.parseByte(temp);
            }


            Key_DH.createPubAndPriKey("Serverpub.txt","Serverpri.txt");

            ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (np));
            Key k2 = (Key)ois.readObject();;
            FileOutputStream f2 = new FileOutputStream("Serverpub.txt");
            ObjectOutputStream b2 = new ObjectOutputStream(f2);
            b2.writeObject(k2);

            SecretKeySpec key = KeyAgree.createKey("Serverpub.txt","Clientpri.txt");


            String k = in.readUTF();//读取加密后密钥

            byte[] encryptKey = H_B.parseHexStr2Byte(k);



            Cipher cp = Cipher.getInstance(mode);
            cp.init(Cipher.DECRYPT_MODE,key);
            byte decryptKey [] = cp.doFinal(encryptKey);//对密钥解密

            SecretKeySpec plainkey=new  SecretKeySpec(decryptKey,mode);
            cp.init(Cipher.DECRYPT_MODE, plainkey);
            byte []plain=cp.doFinal(cipher);

            String formula = new String(plain);//后缀表达式的解密结果

            String serverMD5 = DigestPass.digPass(formula);
            String clientMD5 = in.readUTF();
            if(serverMD5.equals(clientMD5)){
                System.out.println("相等");
                MyDC myDC = new MyDC();
                try{
                    result = myDC.calculate(formula);
                    //后缀表达式formula调用MyDC进行求值
                }catch (ExprFormatException e){
                    result = e.getMessage();
                }catch (ArithmeticException e0){
                    result = "Divide Zero Error";
                }

                out.writeUTF(result);
            }

        }catch (Exception e){
            System.out.println("客户已断开"+e);
        }
    }
}
